<template>
    <canvas class="bg" ref="canvasRef"></canvas>
</template>

<script setup lang="ts">
//字体大小 (乘以devicePixelRatio，为了保持字体的清晰度)
const fontSize = 16*devicePixelRatio
//用于存储当前列的下一个字母位置
let nextColumn:number[] = []
//总列数
let columnsNum = 0
//总行数
let rows = 0
//ref
const canvasRef = ref<HTMLCanvasElement>()
//canvas上下文
let ctx:CanvasRenderingContext2D|null = null

// 获取随机字母
const getRandomChar = () => {
    const str = "console('HelloWorld!')"
    return str[Math.floor(Math.random()*str.length)]
}

// 获取随机颜色
const getRandomColor = () => {
    const colors = [
        '#33B5E5',
        '#0099CC',
        '#AA66CC',
        '#9933CC',
        '#99CC00',
        '#669900',
        '#FFBB33',
        '#FF8800',
        '#FF4444',
        '#CC0000'
    ]
    return colors[Math.floor(Math.random()*colors.length)]
}

const getBaseInfo = () => {
    ctx = canvasRef.value?.getContext('2d') as CanvasRenderingContext2D
    const width = (canvasRef.value?.clientWidth as number)*devicePixelRatio
    const height = (canvasRef.value?.clientHeight as number)*devicePixelRatio
    canvasRef.value!.width = width
    canvasRef.value!.height = height
    //总列数 (列宽等于字体大小)
    columnsNum = Math.floor(width/fontSize)
    //用于存储当前列的下一个字母位置
    nextColumn = new Array(columnsNum).fill(0)
    //总行数
    rows = Math.floor(height/fontSize)
}

const draw = () => {
    //出现上一行透明效果
    ctx!.fillStyle = 'rgba(0,0,0,0.1)'
    ctx!.fillRect(0,0,canvasRef.value!.width,canvasRef.value!.height)
    for(let i = 0;i < columnsNum;i++){
        if(ctx){
            //需要字符、字体颜色、字体大小、位置
            ctx.fillStyle = getRandomColor()
            const char = getRandomChar()
            ctx.font = `${fontSize}px "Roboto Mono"`
            let index = nextColumn[i]
            const x = fontSize*i
            const y = (index + 1)*fontSize
            if(index > rows && Math.random() > 0.9){
                nextColumn[i] = 0
            }else{
                nextColumn[i]++
            }
            ctx.fillText(char,x,y)
        }
    }
}

onMounted(() => {
    getBaseInfo()
    setInterval(() => {
        draw()
    },40)
})
</script>

<style  lang="scss" scoped>
.bg{
    @apply h-full w-full;
    background-color: black;
}
</style>